iT邦幫忙

2021 iThome 鐵人賽

DAY 24
1
自我挑戰組

30天走入亞洲雲端黑馬阿里雲系列 第 24

Day 24 開發者福音無伺服器運算

  • 分享至 

  • xImage
  •  

隨著資訊技術普及與推陳佈新,基礎設施及服務(IaaS)、平台即服務(PaaS)、軟體即服務(SaaS)等等...讓不同的使用者可以依照自身的條件與需求選擇服務,接著要探訪的項目近幾年越來越多開發者熟知的無伺服器服務,使用者不在需要思考伺服器運算環境需要什麼樣的規格、作業系統、負載均衡..等等問題,而在阿里雲提供什麼樣的無伺服器架構服務呢?

函數計算(Function Compute,FC)

阿里雲FC是一個透過事件觸發驅動的全託管運算服務,只要將程式碼邏輯佈署上去,當有條件觸發時才會去執行運算,而未執行觸發FC時不會運行,對於成本降低有相當大的幫助

流程示意圖:

  • 建立服務
  • 新增function
  • 上傳程式碼
  • 設定Tigger條件
  • 執行function
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353cSvsWfWauC.png

實務操作FC:

接著我們要利用FC建立一個自動轉檔的應用,將上傳至指定OSS資料夾內的影片轉碼成hls協議的影音格式並存入另一個OSS資料夾內

架構示意圖:
https://ithelp.ithome.com.tw/upload/images/20211006/20140353O7E6jRfudI.png

  1. 在產品導覽頁找到函數計算服務
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353YfVkxFuM42.png

  2. 點選服務及函數建立服務
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353qAJlTATBm9.png
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353hDmFGIf9gZ.png

  3. 建立服務完成後點選新增函數
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353Ra1Z7pLgWy.png

  4. 下方有提供多樣的模板可以套用,因為要使用OSS觸發驅動這裡選擇事件函數
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353yHsdkR11jR.png

  5. 建立函數名稱,這裡要測試的程式使用的是python3運行,上傳程式碼 (這裡上傳包含ffmpeg程式檔)
    https://ithelp.ithome.com.tw/upload/images/20211006/201403538D6uKtyzFF.png

目錄結構:
ffmpeg
index.py

index.py完整範例程式碼:

# -*- coding: utf-8 -*-
import logging
import oss2
import os
import time
import json
import subprocess
from os import walk

logging.getLogger("oss2.api").setLevel(logging.ERROR)
logging.getLogger("oss2.auth").setLevel(logging.ERROR)

OUTPUT_DST = os.environ["OUTPUT_DST"]
DST_TARGET = os.environ["DST_TARGET"]

def get_fileNameExt(filename):
    (fileDir, tempfilename) = os.path.split(filename)
    (shortname, extension) = os.path.splitext(tempfilename)
    return shortname, extension

def get_beijing_time_str(utc_time_stamp):
    local_time = time.localtime(utc_time_stamp + 8*3600)
    data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
    data_secs = (utc_time_stamp - int(utc_time_stamp)) * 1000
    beijing_time_str = "%s.%03d" % (data_head, data_secs)
    return beijing_time_str

def handler(event, context):
    utc_now = time.time()
    evt = json.loads(event)
    evt = evt["events"]
    oss_bucket_name = evt[0]["oss"]["bucket"]["name"]
    object_key = evt[0]["oss"]["object"]["key"]
    size = evt[0]["oss"]["object"]["size"]
    shortname, extension = get_fileNameExt(object_key)
    M_size = round(size / 1024.0 / 1024.0, 2)
    json_log = {
        "request_id": context.request_id,
        "video_name": object_key,
        "video_format": extension[1:],
        "size": M_size,
        "start_time": get_beijing_time_str(utc_now),
        "processed_video_location": OUTPUT_DST,
    }
    print(json.dumps(json_log))
   
    creds = context.credentials
    auth = oss2.StsAuth(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)
    oss_client = oss2.Bucket(auth, 'oss-%s-internal.aliyuncs.com' % context.region, oss_bucket_name)
    input_path = oss_client.sign_url('GET', object_key, 6 * 3600)
    transcoded_filepath = '/tmp/' + shortname + DST_TARGET
    if os.path.exists(transcoded_filepath):
        os.remove(transcoded_filepath)
    # cmd = ["/code/ffmpeg", "-y", "-i", input_path, "-vf", "scale=640:480", "-b:v", "800k", "-bufsize", "800k", transcoded_filepath]
    # cmd = ["/code/ffmpeg", "-y", "-i", input_path, "-b:v", "1M", "-g", "60", "-hls_time", "2", "-hls_list_size", "0", "-hls_segment_size", "500000",  transcoded_filepath]
    cmd = ["/code/ffmpeg", "-y", "-i", input_path, "-profile:v", "baseline", "-level", "3.0", "-start_number", "0", "-hls_time", "10", "-hls_list_size", "0", transcoded_filepath]
    
    try:
        result = subprocess.run(
            cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
    except subprocess.CalledProcessError as exc:
        err_ret = {
            'request_id': context.request_id,
            'returncode': exc.returncode,
            'cmd': exc.cmd,
            'output': exc.output.decode(),
            'event': evt,
        }
        if exc.stderr:
            err_ret['stderr'] = exc.stderr.decode()
        if exc.stdout:
            err_ret['stdout'] = exc.stdout.decode()
        print(json.dumps(err_ret))
        # if transcode fail, send event to mns queue or insert in do db
        # ...
        raise Exception(context.request_id + " transcode failure")
        return

    filenames = next(walk('/tmp'), (None, None, []))[2]

    for f in filenames:
        if f.find(shortname) != -1:
            oss_client.put_object_from_file(
                os.path.join(OUTPUT_DST, f), ('/tmp/'+ f) )
    
##    oss_client.put_object_from_file(
##        os.path.join(OUTPUT_DST, shortname + DST_TARGET), transcoded_filepath)
    
    # if transcode succ, send event to mns queue or insert in do db
    # ...

    if os.path.exists(transcoded_filepath):
        os.remove(transcoded_filepath)
    
    return "ok"

ffmpeg包為預設的設定,如找不到想測試可以聯絡筆者(噓)

  1. 建立好函數後,會到程式執行頁面,測試執行發現報錯
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353zZJayrTVQr.png
    https://ithelp.ithome.com.tw/upload/images/20211006/201403537MLuNbwRzE.png

  2. 這裡發現忘記先建立OSS觸發條件;權限,建立觸發器:

  • 選擇對象儲存觸發器
  • 需要觸發的OSS Bucket
  • 觸發事件
  • 觸發規則
    最後要授權給OSS觸發器的權限角色,沒有角色則可以直接新建授權
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353JRhgf6DLAK.png
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353VaM1GEVS1d.png
  1. 在OSS Bucket下建立資料夾/vedio/inputs、/vedio/outputs
    https://ithelp.ithome.com.tw/upload/images/20211006/201403530D1RRcs6uW.png

  2. 準備完成後,測試上傳影音檔案,查看/vedio/inputs上傳成功
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353V7XiwfXyoJ.png
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353DHh1wu4MPg.png

  3. 接著打開/vedio/outputs驗證mp4轉碼與m3u8成功,測試也能正常播放 (本影片僅測試使用)
    https://ithelp.ithome.com.tw/upload/images/20211006/20140353KUtobNwGUT.png
    https://ithelp.ithome.com.tw/upload/images/20211006/201403537FqHigIgkH.png

本篇的小應用就到這裡結束,對於經常需要使用影音串流的使用者可以透過FC快速完成轉碼工作並透過無伺服器特性不浪費使用資源,而運用FC能夠讓開發者集思廣益建立更多發揮創意的應用!


上一篇
Day 23 雲上大數據分析
下一篇
Day 25 阿里雲上運行Kubernetes 1 - ACK
系列文
30天走入亞洲雲端黑馬阿里雲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言